package com.googlecode.scenemaker3d.services
{
	import com.googlecode.scenemaker3d.controller.ICameraController;
	import com.googlecode.scenemaker3d.controller.IObjectController;
	
	import flash.events.Event;
	
	import com.googlecode.scenemaker3d.model.World3DModel;
	
	import mx.collections.ArrayCollection;
	import mx.core.UIComponent;
	
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cone;
	import org.papervision3d.objects.primitives.Sphere;
	
	import com.googlecode.scenemaker3d.view.Grid3D;
	
	[Event(name="createDefaultCameras",type="flash.events.Event")]

	public class Initialize extends UIComponent
	{
		private var mWorld:World3DModel;
		private var cCamera:ICameraController;
		private var cObject:IObjectController;
		private var cameraTarget:DisplayObject3D;
		
		public static const ORTHOGRAPHIC_DISTANCE:int = 1000000;
		public static const DEFAULT_CAMERA_DISTANCE:int = 5000;
		public static const DEFAULT_CAMERA_ZOOM:int = 20;
		public static const GRID_WIDTH:int = 5000;
		
		public function Initialize()
		{
			super();
			//Initialize controller(s) (and model).
			cCamera = Control.instance.cameraController;
			cObject = Control.instance.objectController;
			mWorld = Control.instance.world3DModel;
		}
		override protected function createChildren():void{
			//Ensure cameras only ever has one ArrayCollection	
			mWorld.cameras = new ArrayCollection();
			mWorld.objects = new ArrayCollection();
			mWorld.materials = new ArrayCollection();

			createDefaultCameras();
			createGrids();
			createCameraObject();
			createCameraTarget();

		}
		private function createDefaultCameras():void{
			
			//ActualView
			var actualView:Camera3D = new Camera3D();
			actualView.name = CameraViewType.ACTUAL_VIEW;

			actualView.x = 0;
			actualView.y = 500;
			actualView.z = -GRID_WIDTH /2;
			
			actualView.zoom = DEFAULT_CAMERA_ZOOM;
			actualView.lookAt(new DisplayObject3D());
			
			cCamera.addCamera(actualView);
					
			//Main View
			var mainView:Camera3D = new Camera3D();
			mainView.name = CameraViewType.MAIN_VIEW;

			mainView.x = 0;
			mainView.y = 500;
			mainView.z = -GRID_WIDTH /2;
			
			mainView.zoom = DEFAULT_CAMERA_ZOOM;
			
			mainView.lookAt(new DisplayObject3D());
			
			cCamera.addCamera(mainView);
			
			//Top View
			var topView:Camera3D = new Camera3D();
			
			topView.name = CameraViewType.TOP_VIEW;
			topView.x = 0;
			topView.y = ORTHOGRAPHIC_DISTANCE;
			topView.z = 1;//Setting to zero removes view for some reason.
			
			topView.zoom = DEFAULT_CAMERA_ZOOM;
						
			//topView.yUP = false;
			//Camera needs to be rotated 180 degrees.
			topView.lookAt(new DisplayObject3D());
			topView.roll(180);

			cCamera.addCamera(topView);
				
			//Front View	
			var frontView:Camera3D = new Camera3D();
			frontView.name = CameraViewType.FRONT_VIEW;
			
			frontView.x = 0;
			frontView.y = 0;
			frontView.z = -ORTHOGRAPHIC_DISTANCE;
			
			frontView.zoom = DEFAULT_CAMERA_ZOOM;
			
			frontView.lookAt(new DisplayObject3D());
			
			cCamera.addCamera(frontView);
			
			//Side View	
			var sideView:Camera3D = new Camera3D();
			sideView.name = CameraViewType.LEFT_VIEW;

			sideView.x = -ORTHOGRAPHIC_DISTANCE;
			sideView.y = 0;
			sideView.z = 0;
			
			sideView.zoom = DEFAULT_CAMERA_ZOOM;
			
			sideView.lookAt(new DisplayObject3D());
			
			cCamera.addCamera(sideView);
				
			this.dispatchEvent(new Event("createDefaultCameras"));	
		}
		private function createGrids():void{
			var divs:uint = 20;
			var grid:Grid3D;
			//var grid:GridFragmented;
			
		 	for(var i:int=0; i<3; i++){
				grid = new Grid3D(GRID_WIDTH, divs);
				//grid = new GridFragmented(width, divs);
				
				switch(i){
					case 0:
						//Create XZ grid. As is.
						grid.name = CameraViewType.TOP_VIEW;
						break;
					case 1:
						//Create XY grid
						grid.rotationX = -90;
						grid.name = CameraViewType.FRONT_VIEW;
						break
					case 2:
						//Create ZY grid
						grid.rotationX = 90;
						grid.rotationY = 90;
						grid.name = CameraViewType.LEFT_VIEW;
						break;		
				}
				World.instance.scene.addChild(grid);
			} 
		}
		private function createCameraTarget():void{
			var matl:ColorMaterial = new ColorMaterial(0xff0000);
			cameraTarget = new Sphere(matl);
			
			cameraTarget.rotationX = 90;
			cameraTarget.y = -500;
			cameraTarget.z = GRID_WIDTH /2;
			cameraTarget.name = "cameraTarget";
			
			cObject.addObject(cameraTarget);
		}
		private function createCameraObject():void{
			var container:DisplayObject3D = new DisplayObject3D();
			container.name = "cameraObject";
			
			var matl:ColorMaterial = new ColorMaterial(0x00ff00);
			var pointer:Cone = new Cone(matl);
			
			container.addChild(pointer);
			pointer.rotationX = -90;
					
			//cameraObj.lookAt(cameraTarget);
			container.x = 0;
			container.y = 500;
			container.z = -GRID_WIDTH /2;
			
			cObject.addObject(container);
			
		}
		
	}
}